﻿using System.Collections;
using System.Collections.Generic;
using Microsoft.Practices.CompositeUI.UIElements;

namespace Microsoft.Practices.CompositeUI.Collections
{
    /// <summary>
    /// 	Represents an extension site for UI elements.
    /// </summary>
    public class UIExtensionSite : IEnumerable<object>
    {
        #region Fields & Properties

        private readonly IUIElementAdapter _adapter;

        /// <summary>
        /// 	Returns the number of items added to the site.
        /// </summary>
        public int Count
        {
            get
            {
                return _elements.Count;
            }
        }

        #endregion

        #region Collection Fields & Properties

        private readonly List<object> _elements = new List<object>();

        #endregion

        #region Constructors

        /// <summary>
        /// 	Initializes a new instance of the <see cref = "UIExtensionSite" /> class with the provided
        /// 	adapter.
        /// </summary>
        public UIExtensionSite(IUIElementAdapter adapter)
        {
            _adapter = adapter;
        }

        #endregion

        #region Implementation of IEnumerable

        /// <summary>
        /// 	Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// 	A <see cref = "T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public IEnumerator<object> GetEnumerator()
        {
            return _elements.GetEnumerator();
        }

        /// <summary>
        /// 	Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// 	An <see cref = "T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region Add

        /// <summary>
        /// 	Adds an element to the site.
        /// </summary>
        /// <typeparam name = "TElement">The type of the element to be added.</typeparam>
        /// <param name = "uiElement">The element to be added.</param>
        /// <returns>The added element. The adapter may return a different element than was
        /// 	passed; in this case, the returned element is the new element provided by the
        /// 	adapter.</returns>
        public TElement Add<TElement>(TElement uiElement)
        {
            var element = (TElement) _adapter.Add(uiElement);
            _elements.Add(element);
            return element;
        }

        #endregion

        #region Contains

        /// <summary>
        /// 	Determines if the site contains a UI element.
        /// </summary>
        /// <param name = "uiElement">The element to find.</param>
        /// <returns>true if the element is present; false otherwise.</returns>
        public bool Contains(object uiElement)
        {
            return _elements.Contains(uiElement);
        }

        #endregion

        #region Remove

        /// <summary>
        /// 	Removes an item from the site, and removes it from the UI.
        /// </summary>
        /// <param name = "uiElement">The element to be removed.</param>
        public void Remove(object uiElement)
        {
            if (_elements.Contains(uiElement))
            {
                _adapter.Remove(uiElement);
                _elements.Remove(uiElement);
            }
        }

        #endregion

        #region Clear

        /// <summary>
        /// 	Removes all items from the site, and removes them from the UI.
        /// </summary>
        public void Clear()
        {
            foreach (var element in _elements)
            {
                _adapter.Remove(element);
            }
            _elements.Clear();
        }

        #endregion

        #region Duplicate

        internal UIExtensionSite Duplicate()
        {
            return new UIExtensionSite(_adapter);
        }

        #endregion
    }
}